package v2db

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
)

// Table 结构体定义了表的元数据
type Table struct {
	Name   string
	Schema map[string]string // 列名到列类型的映射
	Rows   []*Row            // 存储行数据的切片
}

// Row 结构体定义了一行数据
type Row struct {
	Values map[string]interface{} // 列名到值的映射
}

// LSMDatabase 是简化版的LSM树数据库
type LSMDatabase struct {
	Memtable *Table
	SSTables []*Table
	DataDir  string
}

// NewLSMDatabase 初始化数据库
func NewLSMDatabase(dataDir string) *LSMDatabase {
	return &LSMDatabase{
		Memtable: &Table{},
		SSTables: []*Table{},
		DataDir:  dataDir,
	}
}

// CreateTable 创建表
func (db *LSMDatabase) CreateTable(tableName string, schema map[string]string) {
	db.Memtable = &Table{
		Name:   tableName,
		Schema: schema,
		Rows:   []*Row{},
	}
}

// InsertData 插入数据
func (db *LSMDatabase) InsertData(values map[string]interface{}) {
	row := &Row{Values: values}
	db.Memtable.Rows = append(db.Memtable.Rows, row)
}

// FlushMemtable 将Memtable数据写入SSTable
func (db *LSMDatabase) FlushMemtable() {
	if len(db.Memtable.Rows) == 0 {
		return
	}
	sstable := &Table{
		Name:   db.Memtable.Name,
		Schema: db.Memtable.Schema,
		Rows:   db.Memtable.Rows,
	}
	db.SSTables = append(db.SSTables, sstable)
	db.Memtable = &Table{
		Name:   db.Memtable.Name,
		Schema: db.Memtable.Schema,
		Rows:   []*Row{},
	}
	db.writeTableToDisk(sstable)
}

// writeTableToDisk 将表数据写入磁盘
func (db *LSMDatabase) writeTableToDisk(table *Table) {
	fileName := filepath.Join(db.DataDir, fmt.Sprintf("%s.json", table.Name))
	file, err := os.Create(fileName)
	if err != nil {
		panic(err)
	}
	defer file.Close()

	data, err := json.Marshal(table.Rows)
	if err != nil {
		panic(err)
	}
	_, err = file.Write(data)
	if err != nil {
		panic(err)
	}
}

// readTableFromDisk 从磁盘读取表数据
func (db *LSMDatabase) readTableFromDisk(tableName string) {
	fileName := filepath.Join(db.DataDir, fmt.Sprintf("%s.json", tableName))
	file, err := os.Open(fileName)
	if err != nil {
		panic(err)
	}
	defer file.Close()

	var rows []*Row
	decoder := json.NewDecoder(file)
	err = decoder.Decode(&rows)
	if err != nil {
		panic(err)
	}

	db.SSTables = append(db.SSTables, &Table{
		Name:   tableName,
		Schema: db.Memtable.Schema,
		Rows:   rows,
	})
}

// SelectAll 查询所有数据
func (db *LSMDatabase) SelectAll(tableName string) {
	var allRows []*Row
	for _, sstable := range db.SSTables {
		if sstable.Name == tableName {
			allRows = append(allRows, sstable.Rows...)
		}
	}
	allRows = append(allRows, db.Memtable.Rows...)

	// 打印查询结果
	fmt.Printf("SELECT * FROM %s:\n", tableName)
	for _, row := range allRows {
		fmt.Println(row.Values)
	}
}

func run() {
	// 创建数据目录
	dataDir := "./data"
	os.MkdirAll(dataDir, os.ModePerm)

	db := NewLSMDatabase(dataDir)

	// 创建表
	db.CreateTable("user", map[string]string{"name": "string", "age": "int", "sex": "string"})

	// 插入数据
	db.InsertData(map[string]interface{}{"name": "Alice", "age": 30, "sex": "Female"})
	db.InsertData(map[string]interface{}{"name": "Bob", "age": 25, "sex": "Male"})

	// 将Memtable数据写入SSTable
	db.FlushMemtable()

	// 再次插入数据到Memtable
	db.InsertData(map[string]interface{}{"name": "Charlie", "age": 35, "sex": "Male"})

	// 查询所有数据
	db.SelectAll("user")
}
